
import React, { Component, PureComponent, forwardRef  } from 'react'
import { connect } from 'react-redux'
import { Form, Input, Button, Radio, Row, Col, Select, InputNumber, TreeSelect, Cascader, Checkbox, DatePicker  } from 'antd';

import { cloneDeep } from 'lodash'

import $axios from '@/plugins/axios'
import { $basics } from '@/plugins/eng_config'

const { Option } = Select;
const { TreeNode } = TreeSelect;
const { Search, TextArea } = Input

class MyForm extends PureComponent {

    formRef = React.createRef();

    state = {
        layout: 'horizontal'
    }

    constructor (props) {
        super(props)

        const initialValues = props.initialValues || {}

        props.list.forEach((item, index) => {
          if([undefined, null, ''].includes(initialValues[item.prop]) && item.value){
              initialValues[item.prop] = item.value
          }
          if(item.hasOwnProperty('data')){
            Array.isArray(item.data) ? item.options = item.data : item.options = []
          }
        })
        this.state.initialValues = cloneDeep(initialValues) 
        this.state.list = cloneDeep(props.list || [])
    }

    getFieldsValue = () => {
      return cloneDeep(this.formRef.current.getFieldsValue())
    }

    componentDidMount = (a, b) => {
        const { list, initialValues } = this.state
        this.init(list, initialValues)
    }

    init = (list, initialValues) => {
        list.forEach((item, index) => {
            item.rules = []

            if(item.must){
                item.rules.push({required: true, message: item.label + ' 是必须项' })
            }

            if(item.validator){
                item.rules.push({validator: item.validator.bind('', this.formRef)})
            }

            const sign = (item.dictCode && item.src) || (item.dictCode && item.fn) || (item.src && item.fn)
            if(sign){
              console.error('表单配置文件中 属性 fn, dictCode, src 不要同时存在，注意代码书写。')
            }

            if (item.type === 'OrgCascader'){ // 编制单位 菜单 独有。。
              this.initOrgOptions(list, index)
            }

            if (typeof item.dictCode === 'string'){  // 字符串 -- 远程 获取 字典值的 参数
              this.getDicts(list, index, list[index].time)
            }

            if(item.src){   // 说明需要远程单独接口获取数据源
                this.getOriginOptions(list, index, list[index].time)
            }

            if(item.fn && typeof item.fn === 'function'){  // 必须返回一个 Promise
              item.fn().then(res => {
                list[index].options = res || []
                this.setState({
                    list: cloneDeep(list)
                })
              })
            }

        })
        this.setState({
          list: cloneDeep(list)
            // initialValues: cloneDeep(initialValues)
        })
    }

    formItemOperate = ({ item, value }) => {
      const { formItemCallback } = this.props
      if (typeof formItemCallback === 'function') {
        formItemCallback({ item, value })
      }
    }

    initOrgOptions = (list, index) => {

      const orgList = cloneDeep(this.props.initialValues[list[index].prop] || [])
      const value = [...orgList].pop() // 去掉最后一个

      if( value ){    // 说明有初始化 -- 这个时候 需要回显数据-- 懒加载模式下 需要逐级获取 可选数据
        this.getOrgLazyOptions(list, index, orgList, value)
        return
      }

      $axios.post(`${$basics}/basics/org/tree`, {}).then(res => { // 一般 只 默认获取 第一级 数据
        const arr = res.body || []
        const options = arr.map(r => (Object.assign(r, {
          title: r.name,
          value: r.id,
          isLeaf: false,
          children: null
        })))
        list[index].options = options
        this.setState({
          list: cloneDeep(list)
        })
      })
    }

    getOrgLazyOptions = (list, index, orgList, value) => {
      //   orgList  --  这个 参数是 当前所选 数据的 数组 例如 [43]、[43, 4301]、[43, 4301, 430126]
      //  获取 当前 登录用户 的 机构id, 长度 2位 -- 省&管理员     4 -- 市     6 -- 县
      const { companyId, length = companyId.length } = this.props.userInfo
      const requestList = []
      const provinceOptions = $axios.post(`${$basics}/basics/org/tree`, {})
      requestList.push(provinceOptions)

      for (let i = 0; i < orgList.length - 1; i ++){
        requestList.push($axios.post(`${$basics}/basics/org/tree`, { loadType: '3', parentId: orgList[i]}))
      }

      Promise.all(requestList).then(resList => {
        resList.forEach((r, index) => {
          if(Number(r.code) === 200){
            resList[index] = r.body.map(item => {
              return Object.assign(item, {
                title: item.name,
                value: item.id,
                isLeaf: false,
                children: null
              })
            })
          }
        })

        // 进行 下一步 操作
        if (length === 2) {   // 当前登录用户属于 省公司
          if (value.length === 2) { // 选择了  省公司

          }
          if (value.length === 4) { // 选择了 市公司
            const item = resList[0].find(r => r.value === orgList[0])
            item.children = resList[1]
          }
          if (value.length === 6) {   //  选择了 县公司
            const item = resList[0].find(r => r.value === orgList[0])
            item.children = resList[1]
            const itemCity = resList[1].find(r => r.value === orgList[1])
            itemCity.children = resList[2]
          }
        }

        if (length === 4) {    //  市公司
          if (value.length === 4) { // 选择了 市公司
            list[index].options = resList[0]
          }
          if (value.length === 6) {   //  选择了 县公司
            const item = resList[0].find(r => r.value === orgList[1])
            item.children = resList[1]
          }
        }

        if (length === 6) {      //  县公司
          if (value.length === 6) {   //  选择了 县公司
            const item = resList[0]
            item.children = []
          }
        }

        list[index].options = resList[0]
        this.setState({ list: cloneDeep(list) })

      }).catch((err) => {
        console.error(err)
      })

    }

    getLoadData = (list, index) => {
      return (selectedOptions) => {
        const targetOption = selectedOptions[selectedOptions.length - 1];
        targetOption.loading = true;

        const param = {
          loadType: "3",
          parentId: targetOption.id
        }
        $axios.post(`${$basics}/basics/org/tree`, param).then(res => {
          const arr = res.body || []
          let children = null
          if (arr.length > 0) {
            children = arr.map(r => (Object.assign(r, {
              title: r.name,
              value: r.id,
              isLeaf: false,
              children: null
            })))
          }

          targetOption.children = children
          targetOption.isLeaf = children ? false : true
          targetOption.loading = false;
        }).finally(() => {
          this.setState({
            list: cloneDeep(list)
          })
        })
      }
    }

    getDicts = (list, index, time=2000) => {
      const param = {
        dicTypes: list[index].dictCode,
        dictBusiType: 'BUSI_DICT'
      }
      $axios.post(`${$basics}/basics/dict/list`, param).then(res => {
        list[index].options = res.body[list[index].dictCode] || []
        this.setState({
          list: cloneDeep(list)
        })
      })
    }

    getOriginOptions = (list, index, time=2000) => {
        setTimeout(() => {
            list[index].options = [1,2,3,4,5,6,7,8]
            this.setState({
                list: cloneDeep(list)
            })              
        }, time)
    }

    onValuesChange = (value, formValue) => {

        // console.log('查看 props .....   ', this.props)

        // const onValuesChange = this.props.onValuesChange

        (typeof this.props.onValuesChange === 'function') && this.props.onValuesChange(value, formValue, this)
    }

    onFinish = (values) => {
      
    }

    clickMe = () => {

    }

    validate = () => {
        // return this.formRef.current.validateFields(['field1'])
        return this.formRef.current.validateFields()
    }

    validator = (formInstance, rule, value) => {

        if(value && value.length <10) return Promise.reject('长度必须 超过 10 位')
        return Promise.resolve()

    }

    // getSlot = (item) => {
    //   console.log( '查看 children。。。。。。。。。。')
    //   const children = this.props.children()
    //   console.log(children)
    //   // if(Array.isArray(children)){   // 多个 slot
    //   //   const slot = children.find(r => r.props.slot === item.prop)
    //   //   return slot
    //   // }
    //   // if(item.prop === children.props.slot){
    //   //   return children
    //   // }
    // }

    render() {
        const { list, initialValues } = this.state
        const { labelAlign } = this.props

        return (
            <>
              {/* { */}
               {/* forwardRef((props, _ref) => { */}
                   {/* return ( */}
                    <Form
                        preserve={false}
                        className='formBaseClass'
                        ref={this.formRef}
                        layout={this.state.layout}
                        // labelCol={{span: 6}}
                        onFinish={this.onFinish}
                        initialValues={initialValues}
                        labelAlign={labelAlign}
                        onValuesChange={this.onValuesChange}
                    >
                        <Row gutter={12}>

                            {

                              list.map((item, index) => {
                                if(item.type === 'Input') {
                                  const Prefix = item.prefix;
                                  return (
                                    <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules} hidden={item.hidden}>
                                        <Input
                                          type={item.isPassword ? 'password' : null }
                                          size={ item.size || 'default' }
                                          prefix={Prefix ? <Prefix /> : null }
                                          placeholder={item.placeholder || item.label} />
                                      </Form.Item>
                                    </Col>
                                  )
                                }

                                if (item.type === 'TextArea'){
                                  return (
                                    <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules} hidden={item.hidden}>
                                        <TextArea
                                          rows={ item.rows || 4}
                                          size={item.size || 'default'}
                                          placeholder={item.placeholder || item.label} />
                                      </Form.Item>
                                    </Col>
                                  )
                                }

                                if (item.type === 'Search') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                    <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <Search onSearch={(value) => this.formItemOperate({ item, value })} placeholder={item.placeholder || item.label} />
                                    </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'Select') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                          <Select
                                              size={item.size || 'default'}
                                              showSearch
                                              mode={item.multiple ? 'multiple' : null}
                                              placeholder={item.placeholder || item.label}
                                              optionFilterProp="children"
                                              filterOption={(input, option) =>
                                                  option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                                              }
                                          >
                                            {
                                              (item.options || []).map((innerItem, innerIndex) => (
                                                <Option value={innerItem.dicValue || innerItem.value} key={innerIndex}>{innerItem.dicLabel || innerItem.label}</Option>
                                              ))
                                            }
                                          </Select>
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'InputNumber') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <InputNumber size={item.size || 'default'} min={item.min} max={item.max} placeholder={item.placeholder || item.label} />
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'RadioGroup') return (
                                  <Col span={item.span ||12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <Radio.Group size={item.size || 'default'} options={item.options || []} placeholder={item.placeholder || item.label} />
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'slot'){
                                  return (
                                    <Col span={item.span || 12} key={item.prop}>
                                      { typeof this.props.getSlot === 'function' ? this.props.getSlot(item, this) : null }
                                    </Col>
                                  )
                                }

                                if(item.type === 'TreeSelect') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                          <TreeSelect
                                              showSearch
                                              size={item.size || 'default'}
                                              style={{ width: '100%' }}
                                              dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                                              placeholder={item.placeholder || item.label}
                                              allowClear
                                              treeDefaultExpandAll
                                              treeData={item.options}
                                          >
                                          </TreeSelect>
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'OrgCascader') return (  // 编制单位 单独 一个 动态 级联 组件
                                  <Col span={item.span || 12} key={item.prop}>
                                    <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <Cascader loadData={this.getLoadData(list, index)} fieldNames={{ label: 'title' }} size={item.size || 'default'} options={item.options} placeholder={item.placeholder || item.label} changeOnSelect />
                                    </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'Cascader') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <Cascader  fieldNames={{ label: 'title' }} size={item.size || 'default'} options={item.options} placeholder={item.placeholder || item.label} />
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'Checkbox') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} valuePropName="checked" rules={item.rules}>
                                      <Checkbox size={item.size || 'default'}>Checkbox</Checkbox>
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'CheckboxGroup') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <Checkbox.Group size={item.size || 'default'} options={item.options || []} />
                                      </Form.Item>
                                  </Col>
                                )

                                if(item.type === 'DatePicker') return (
                                  <Col span={item.span || 12} key={item.prop}>
                                      <Form.Item label={item.label} name={item.prop} rules={item.rules}>
                                      <DatePicker style={{ display: 'block' }} picker={item.picker || null} size={item.size || 'default'} placeholder={item.placeholder || item.label}/>
                                      </Form.Item>
                                  </Col>
                                )

                              })
                            }
                        </Row>
                    </Form>
                   {/* )
                 })
               } */}
            </>
        )
    }
}

// export default forwardRef(MyForm)

// export default MyForm

export default connect(
	state => ({
    userInfo: state.userInfo
	}),//映射状态
  null, null, { forwardRef: true }
)(MyForm)